<script setup name="Switch">
import { useWebSocket } from "@vueuse/core";
import { Splitpanes, Pane } from "splitpanes";
import "splitpanes/dist/splitpanes.css";
import { generalExecutor } from "@/api/tools";
import useUserStore from "@/store/modules/user";
import GenerateStr from "./components/GenerateStr";

const { proxy } = getCurrentInstance();

const inputs = ref("");
const drawer = ref(false);
const funcName = ref();
const loading = ref(false);
const outputs = ref("");
const wsInstance = ref();

const type = computed(() => {
  if (funcName.value) {
    return switchOptions
      .map((item) => item.children)
      .reduce((x, y) => {
        return x.concat(y);
      }, [])
      .find((item) => item.value == funcName.value).type;
  } else {
    return null;
  }
});

const component = computed(() => {
  if (funcName.value) {
    return switchOptions
      .map((item) => item.children)
      .reduce((x, y) => {
        return x.concat(y);
      }, [])
      .find((item) => item.value == funcName.value).component;
  } else {
    return null;
  }
});

const template = computed(() => {
  if (funcName.value) {
    return switchOptions
      .map((item) => item.children)
      .reduce((x, y) => {
        return x.concat(y);
      }, [])
      .find((item) => item.value == funcName.value).template;
  } else {
    return null;
  }
});

const switchOptions = [
  {
    value: "dataFormatter",
    label: "数据格式化",
    children: [
      {
        type: "default",
        value: "ipv42int",
        label: "ipv4->int",
        template: '["192.168.1.1", "192.168.1.2", "192.168.1.3"]',
      },
      {
        type: "default",
        value: "int2ipv4",
        label: "int->ipv4",
        template: "[3232235777,3232235778,3232235779]",
      },
      {
        type: "default",
        value: "ipv62int",
        label: "ipv6->int",
        template: '["2408:8720:806:300:70::78"]',
      },
      {
        type: "default",
        value: "str2hex",
        label: "str->hex",
        template: '["将字符串转换为16进制字符串"]',
      },
      {
        type: "default",
        value: "hex2str",
        label: "hex->str",
        template:
          '["e5b0863136e8bf9be588b6e5ad97e7aca6e4b8b2e8bdace68da2e4b8bae5ad97e7aca6e4b8b2"]',
      },
      {
        type: "default",
        value: "time2int",
        label: "time->int",
        template: '["2023-01-01 00:00:00"]',
      },
      {
        type: "default",
        value: "str2md5hex",
        label: "str->md5",
        template: '["Hello, World!"]',
      },
      {
        type: "default",
        value: "science2int",
        label: "science->int",
        template: '["1.23e+05"]',
      },
    ],
  },
  {
    value: "dataGenerater",
    label: "数据生成器",
    children: [
      {
        type: "customize",
        value: "generate_str",
        label: "字符串生成",
        template:
          '<task str_id="$id" str_group="ip" str_groupid="1"><[DATA[*@$sip:*$direc$dip:*]]></task>',
        component: GenerateStr,
      },
    ],
  },
];

const data = reactive({
  queryParams: {
    type: "default",
    inputs: inputs,
    userId: undefined,
    funcName: funcName,
    funcParams: undefined,
  },
});

const { queryParams } = toRefs(data);

/** 转换类型切换事件 */
function handleSelectChange(val) {
  funcName.value = val;
  inputs.value = template.value;
}

function submit() {
  drawer.value = false;
}

/** 转换按钮 */
async function handleExecute() {
  outputs.value = "";
  if (queryParams.value.funcName) {
    let userInfo = await useUserStore().getInfo();
    let url = `ws://${window.location.host}:8000/ws/console/${funcName.value}/${userInfo.data.user.id}/`;
    // 如果已经存在一个WebSocket连接，则关闭它，解决方法再次执行时，Websocket缓存导致的重复数据
    if (wsInstance.value && wsInstance.value.status == "OPEN") {
      wsInstance.value.close();
    }
    // 采用 useWebSocket 新建的 WebSocket 链接
    wsInstance.value = useWebSocket(url, {
      autoReconnect: {
        retries: 3,
        delay: 1000,
      },
      autoClose: true,
      onConnected(ws) {
        if (wsInstance.value.status === "OPEN") {
          loading.value = true;
          queryParams.value.type = type;
          queryParams.value.funcParams = proxy.$refs.currentCompRef.form
            ? proxy.$refs.currentCompRef.form
            : {};
          queryParams.value.userId = userInfo.data.user.id;
          generalExecutor(queryParams.value)
            .then((res) => {
              loading.value = false;
              if (res.data) {
                outputs.value = res.data;
              }
              proxy.$modal.msgSuccess(res.msg);
            })
            .catch((error) => {
              loading.value = false;
            })
            .finally(() => {
              loading.value = false;
            });
        }
      },
      onMessage(ws, event) {
        outputs.value += event.data;
      },
    });
  } else {
    proxy.$modal.msgWarning("请选择运行模式！");
  }
}
</script>

<template>
  <div class="app-container">
    <splitpanes class="default-theme" horizontal style="height: auto">
      <pane>
        <el-card class="box-card" style="height: 100%">
          <template #header>
            <div class="card-header">
              <span>输入</span>
              <div class="right-toolbar">
                <el-button plain type="primary" @click="drawer = true"
                  >设置</el-button
                >
              </div>
            </div>
          </template>
          <el-input v-model="inputs" type="textarea" :rows="15" />
        </el-card>
        <el-drawer v-model="drawer" direction="rtl">
          <template #header>
            <h2>运行参数设置</h2>
          </template>
          运行模式：
          <el-tree-select
            accordion
            v-model="funcName"
            :data="switchOptions"
            :check-strictly="false"
            :render-after-expand="false"
            placeholder="请选择运行模式"
            @change="handleSelectChange"
          />
          <el-divider />
          <keep-alive>
            <component :is="component" ref="currentCompRef" />
          </keep-alive>
          <template #footer>
            <div style="flex: auto">
              <el-button @click="drawer = false">取消</el-button>
              <el-button type="primary" @click="submit">确定</el-button>
            </div>
          </template>
        </el-drawer>
      </pane>
      <pane>
        <el-card class="box-card" style="height: 100%">
          <template #header>
            <div class="card-header">
              <span>输出</span>
              <div class="right-toolbar">
                <el-button
                  plain
                  type="primary"
                  :loading="loading"
                  @click="handleExecute"
                  >运行</el-button
                >
              </div>
            </div>
          </template>
          <el-input v-model="outputs" type="textarea" :rows="15" />
        </el-card>
      </pane>
    </splitpanes>
  </div>
</template>
